index.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. "use client";
  2. import ButtonOwn from "@/components/ButtonOwn";
  3. import { Link, useRouter } from "@/i18n";
  4. import { useUserInfoStore } from "@/stores/useUserInfoStore";
  5. import { Toast } from "antd-mobile";
  6. import clsx from "clsx";
  7. import { useTranslations } from "next-intl";
  8. import { useSearchParams } from "next/navigation";
  9. import { FC, FormEvent, PropsWithChildren, useState } from "react";
  10. import { useFormStatus } from "react-dom";
  11. import { loginAction, registerAction } from "./action";
  12. import "./style.scss";
  13. /**
  14. * @description 登录注册From表单
  15. * @param {string} type 使用类型 login 或 register
  16. * @param {string} msgError 错误提示 login 或 register
  17. * @param {(params: any) => void} callbackFun 回调方法
  18. */
  19. export interface FromComProps {
  20. type?: string;
  21. msgError?: string;
  22. callbackFun?: (params: any) => void;
  23. }
  24. const initialState = {
  25. message: "",
  26. };
  27. const Submit = (props: { text: string }) => {
  28. const { text } = props;
  29. const { pending, data } = useFormStatus();
  30. return (
  31. <ButtonOwn disabled={pending} type={"submit"} active={true}>
  32. {text}
  33. </ButtonOwn>
  34. );
  35. };
  36. const FromCom: FC<PropsWithChildren<FromComProps>> = ({ type = "login", msgError = "" }) => {
  37. const t = useTranslations("LoginPage");
  38. let [pwdVisible, setPwdVisible] = useState(false);
  39. const searchParams = useSearchParams();
  40. const router = useRouter();
  41. const { setUserInfo } = useUserInfoStore();
  42. const [loginFormStatus, setLoginFormStatus] = useState<{ success?: boolean; message?: string }>(
  43. {}
  44. );
  45. const formAction = async (formData: FormData) => {
  46. if (!formData.get("userPhone")) {
  47. setLoginFormStatus({ success: false, message: "Please input phoneNumber" });
  48. return;
  49. }
  50. if (!formData.get("pwd")) {
  51. setLoginFormStatus({ success: false, message: "Please input password" });
  52. return;
  53. }
  54. Toast.show({ icon: "loading", duration: 3000, maskClickable: false });
  55. if (type === "login") {
  56. const result = await loginAction(formData);
  57. setUserInfo(result.user);
  58. setLoginFormStatus(result);
  59. if (result.success) {
  60. router.replace(searchParams.get("redirect") || "/");
  61. }
  62. } else {
  63. formData.set("referrer_code", sessionStorage.getItem("shareId") ?? "");
  64. const result = await registerAction(formData);
  65. if (result.success) {
  66. // const loginResult = await loginAction(formData);
  67. // setUserInfo(loginResult.user);
  68. // setToken(loginResult.token!);
  69. // setLoginFormStatus(result);
  70. // if (result.success) {
  71. // router.replace(searchParams.get("redirect") || "/");
  72. // }
  73. router.replace("/login");
  74. } else {
  75. setLoginFormStatus({ success: false, message: result.message });
  76. }
  77. }
  78. Toast.clear();
  79. };
  80. const onsubmit = async (e: FormEvent<HTMLFormElement>) => {
  81. e.preventDefault();
  82. const formData = new FormData(e.target as HTMLFormElement);
  83. await formAction(formData);
  84. };
  85. const spanClassName = clsx("iconfont", {
  86. "icon-kejian": pwdVisible,
  87. "icon-bukejian": !pwdVisible,
  88. });
  89. return (
  90. <div className="FromCom">
  91. <form onSubmit={onsubmit}>
  92. <div className="phoneInput">
  93. <span className="after">{t("areaCode")}</span>
  94. <input name="userPhone" type="tel" placeholder={t("Celular")} maxLength={11} />
  95. </div>
  96. <div className="passwordInput">
  97. <input
  98. name="pwd"
  99. type={pwdVisible ? "text" : "password"}
  100. placeholder={t("Senha")}
  101. maxLength={12}
  102. />
  103. <span
  104. className={spanClassName}
  105. onClick={() => setPwdVisible(!pwdVisible)}
  106. ></span>
  107. </div>
  108. <div className="btnContent">
  109. <div className="tips"> {loginFormStatus.message} </div>
  110. <Submit text={type == "login" ? "Login" : t("register")} />
  111. </div>
  112. </form>
  113. <div className="link">
  114. {type == "login" ? (
  115. <>
  116. <Link href="/resetPhone">{t("forgetPwd")}</Link>
  117. <Link href="/register">{t("registerGo")}</Link>
  118. </>
  119. ) : (
  120. <Link href="/login" className="active" replace>
  121. {t("loginGo")}
  122. </Link>
  123. )}
  124. </div>
  125. </div>
  126. );
  127. };
  128. export default FromCom;